﻿using Ldt.DataEngin.Assemble;
using Ldt.DataEngine.DataFlowParse.Model;
using LdtJudge.DataEngine.CallInterface.CommHelp;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.CommModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace Ldt.DataEngin.PCPackage
{
  public class LdtDataEnginPCPackage
  {
    public Dictionary<string, int> moduleProcess = new Dictionary<string, int>();
    public List<ConfigModel> configmodels = new List<ConfigModel>();
    private string configRootDir = string.Empty;
    public MainInputParameterModel inputParameter;
    public DataContext dataContext;
    private static LdtDataEnginPCPackage.CallBackFun_EventHandler _callBackFun;

    public int progressValue { get; set; }

    public LdtDataEnginPCPackage(
      MainInputParameterModel mainInputParameter,
      IFreeSql sysFreeSql,
      IFreeSql commonManageFreeSql,
      string configRootPath)
    {
      this.inputParameter = mainInputParameter;
      FreeSQLHelp.AddFreeSQLEntity("LdtCommonManage", commonManageFreeSql);
      FreeSQLHelp.AddFreeSQLEntity("Ldt_JudgeDocSystem", sysFreeSql);
      this.configRootDir = configRootPath;
    }

    public List<ConfigModel> GetFlowConfig(LdtDataEnginPCPackage.FlowType flowType)
    {
      string empty = string.Empty;
      FlowConfig flowConfig = new FlowConfig();
      flowConfig.ConfigRootPath = this.configRootDir;
      MsgStruct msgStruct = (MsgStruct) JsonConvert.DeserializeObject<MsgStruct>(HttpHelp.DeCodeBase64new(65001, flowType != LdtDataEnginPCPackage.FlowType.Ana ? flowConfig.GetOptimizeCfgInfo(this.inputParameter.CaseType, this.inputParameter.CaseCause, (string) null) : flowConfig.GetAnalysisFlow(this.inputParameter.CaseType, this.inputParameter.DocID, this.inputParameter.AppId, this.inputParameter.CourtId, this.inputParameter.CaseCause)));
      if (msgStruct.Result.Code == "0")
        this.configmodels = ((IEnumerable<ConfigModel>) msgStruct.Body.ModuleConfig).ToList<ConfigModel>();
      return this.configmodels;
    }

    public void ExtractWrap(
      LdtDataEnginPCPackage.CallBackFun_EventHandler callBackFun)
    {
      Dictionary<string, string> analysisResult = new Dictionary<string, string>();
      this.inputParameter.SourceContent = this.GetFileContent(this.inputParameter.SourceContent);
      MainPCPackage mainPcPackage = new MainPCPackage(this.inputParameter);
      mainPcPackage.LogShow = new LogShow(this.LogMessage);
      mainPcPackage.ProcessShow = new ProcessShow(this.SetProcess);
      mainPcPackage.ModuleProcessShow = new ModuleProcessShow(this.SetModuleProcess);
      mainPcPackage.configmodels = this.GetFlowConfig(LdtDataEnginPCPackage.FlowType.Ana);
      mainPcPackage.ExtractWrap();
      LdtDataEnginPCPackage._callBackFun = callBackFun;
      if (LdtDataEnginPCPackage._callBackFun == null)
        return;
      analysisResult.Add("CaseElement", mainPcPackage.dataContext.DataLayerAns?.AnalysisResultsXml?.OuterXml);
      analysisResult.Add("CaseCauseElement", mainPcPackage.dataContext.DataLayerAns?.ElementAnalysisResults?.OuterXml);
      if (mainPcPackage.dataContext.DataLayerAns?.ReasonDataModel != null)
      {
        XmlDocument xmlDocument = new XmlUtilCommon()
        {
          dataContext = mainPcPackage.dataContext
        }.DataModelByXml(mainPcPackage.dataContext.DataLayerAns?.ReasonDataModel, "", true);
        analysisResult.Add("ReasonElement", xmlDocument.OuterXml);
      }
      LdtDataEnginPCPackage._callBackFun(analysisResult);
    }

    public string OptimizationWrap()
    {
      MainPCPackage mainPcPackage = new MainPCPackage(this.inputParameter);
      mainPcPackage.configmodels = this.GetFlowConfig(LdtDataEnginPCPackage.FlowType.Opt);
      mainPcPackage.OptimizationWrap();
      return mainPcPackage.dataContext.DataLayerOpt.OptimizationXml.OuterXml;
    }

    public void LogMessage(string message, LogMessageType messagetype)
    {
      Console.WriteLine(message);
    }

    public void SetProcess(string fileId, int nValue)
    {
      this.progressValue = nValue;
    }

    public void SetModuleProcess(string moduleName, int processValue)
    {
      if (this.moduleProcess.ContainsKey(moduleName))
        this.moduleProcess[moduleName] = processValue;
      else
        this.moduleProcess.Add(moduleName, processValue);
    }

    public string GetFileContent(string docContent)
    {
      return BllDataHandle.GetDocText(Convert.FromBase64String(docContent));
    }

    public enum FlowType
    {
      Ana,
      Opt,
    }

    public delegate void CallBackFun_EventHandler(Dictionary<string, string> analysisResult);
  }
}
